# -*- coding: utf-8 -*-
import csv
from datetime import datetime, timedelta, date

from django import forms
from django.http import HttpResponseRedirect
from django.http import HttpResponse
from django.core.urlresolvers import reverse

from google.appengine.ext.db import djangoforms
from google.appengine.ext import db
from google.appengine.api import memcache

from base.models import School, TempInvoice, INVOICE_STATUS, TempInvoiceManager
from base.util.decorators import login_required, render_to, admin_required
from base.util.emc import _kr, _kr_u_, short_name_, kr_stage_, en_stage_, kr_money_
import logging

ETEACHER_PAY = 32
DALLA = 1150

class TempInvoiceForm(djangoforms.ModelForm):
    class Meta:
        model = TempInvoice
        exclude = ('id',)

#    def clean_school(self):
#        cleaned_data = self.cleaned_data
#        school = cleaned_data['school']
#        if not school:
#            logging.info('3333')
#            raise forms.ValidationError(u"학교명을 선택해야 합니다.")
#        return school

    def clean(self):
        cleaned_data = self.cleaned_data
        school = cleaned_data['school']
        if not school:
            raise forms.ValidationError(u'학교명을 선택해야 합니다.')
        year = cleaned_data['year']
        month = cleaned_data['month']
        type = cleaned_data['type']
        temp_invoice = TempInvoiceManager.is_exist(school, year, month, type)
        if not self.instance and temp_invoice:
            raise forms.ValidationError(u'같은 invoice가 이미 존재합니다.')
        if self.instance:
            if (self.instance.school != school or
                self.instance.year != year or
                self.instance.month != month or
                self.instance.type != type) and\
                temp_invoice:
                raise forms.ValidationError(u'같은 invoice가 이미 존재합니다.')
        return cleaned_data


@admin_required
@render_to('temp_invoice/form.html')
def create(request):
    data = request.GET.copy()
    school_id = data.get('school', '').strip()
    month = data.get('month', '1').strip()
    if school_id:
        school = School.get_using_id(int(school_id))
        form = TempInvoiceForm(initial={'school': school.key(),
                                    'month': int(month),
                                    })
    else:
        form = TempInvoiceForm()

    if request.method == 'POST':
        form = TempInvoiceForm(request.POST)
        if form.is_valid():
            invoice_no = memcache.incr('invoice_no')
            temp_invoice = form.save(False)
            temp_invoice.no = invoice_no
            if not temp_invoice.total_price:
                temp_invoice.total_price = temp_invoice.count_classes * temp_invoice.uint_price
            else:
                temp_invoice.count_classes = 0
            temp_invoice.put()
            return temp_invoice.get_absolute_url
    return {
            'form': form,
            }

@admin_required
@render_to('temp_invoice/detail.html')
def detail(request, invoice_id):
    temp_invoice = TempInvoice.get_using_id(int(invoice_id))
    return {'invoice': temp_invoice,}

@admin_required
def detail_csv(request, invoice_id):
    invoice = TempInvoice.get_using_id(int(invoice_id))
    fname = str(invoice.month) + '_' + invoice.school.en_name + '_invoice.csv'
    response = HttpResponse(mimetype='text/csv')
    response['Content-Disposition'] = 'attachment; filename=' + fname

    writer = csv.writer(response)
    writer.writerow([
                     invoice.no,
                     str(invoice.month) + _kr_u_('월'),
                     _kr(invoice.school.name) + _kr(kr_stage_(invoice.school.stage)),
                     invoice.school.en_name + en_stage_(invoice.school.stage),
                     short_name_(invoice.school.en_name) + invoice.school.stage,
                     _kr_u_(invoice.invoiced_date.strftime('%Y년 %m월 %d일')),
                     invoice.invoiced_date.strftime('%d %B %Y'),
                     _kr_u_(invoice.start_date.strftime('%Y년%m월%d일')) + '~' + _kr_u_(invoice.end_date.strftime('%Y년%m월%d일')),
                     invoice.start_date.strftime('%d %B %Y') + ' ~ ' + invoice.end_date.strftime('%d %B %Y'),
                     invoice.count_classes,
                     invoice.uint_price,
                     invoice.total_price,
                     _kr_u_('일금 ') + _kr(kr_money_(str(invoice.total_price))) + _kr_u_('정'),
                     invoice.school.coordinator.first_name
                     ])
    return response

@admin_required
@render_to('temp_invoice/form.html')
def change(request, invoice_id):
    temp_invoice = TempInvoice.get_using_id(int(invoice_id))
    form = TempInvoiceForm(request.POST or None, instance=temp_invoice)
    if form.is_valid():
        temp_invoice = form.save()
        return temp_invoice.get_absolute_url
    return {'form': form}

@admin_required
@render_to('temp_invoice/list.html')
def delete(request, invoice_id):
    temp_invoice = TempInvoice.get_using_id(int(invoice_id))
    year = temp_invoice.year
    temp_invoice.delete()
    return HttpResponseRedirect(reverse('base.views.temp_invoice.year_list', args=(year,)))


@admin_required
@render_to('temp_invoice/list.html')
def year_list(request, year):
#    query = TempInvoice.gql('WHERE year=:year ORDER BY month ASC', year=int(year))
#    invoices = query.fetch(1000)

    unpaid_dic = {}
    paid_dic = {}
    total_paid_dic = {}
    unpaid_school_dic = {}
    paid_school_dic = {}
    total_class_count_dic = {}
    for m in xrange(1, 13):
        query = TempInvoice.gql('WHERE year=:year AND month=:month ORDER BY month ASC', year=int(year), month=int(m))
        month_invoices = query.fetch(1000)
        paid_dic[m] = sum([month.total_price for month in month_invoices if month.status == INVOICE_STATUS[1]])
        unpaid_dic[m] = sum([month.total_price for month  in month_invoices if month.status != INVOICE_STATUS[1]])
        total_paid_dic[m] = sum([month.total_price for month  in month_invoices])
        unpaid_school_dic[m] = sum([1 for month  in month_invoices if month.status != INVOICE_STATUS[1]])
        paid_school_dic[m] = sum([1 for month  in month_invoices if month.status == INVOICE_STATUS[1]])
        total_class_count_dic[m] = sum([month.count_classes for month  in month_invoices])

    paid_dic[13] = sum(paid_dic.values())
    unpaid_dic[13] = sum(unpaid_dic.values())
    total_paid_dic[13] = sum(total_paid_dic.values())
    unpaid_school_dic[13] = sum(unpaid_school_dic.values())
    paid_school_dic[13] = sum(paid_school_dic.values())
    total_class_count_dic[13] = sum(total_class_count_dic.values())
    return {
            'paid_dic': paid_dic,
            'unpaid_dic': unpaid_dic,
            'total_paid_dic': total_paid_dic,
            'unpaid_school_dic': unpaid_school_dic,
            'paid_school_dic': paid_school_dic,
            'total_class_count_dic': total_class_count_dic,
            }

@admin_required
def year_list_csv(request, year):
    query = TempInvoice.gql('WHERE year=:year ORDER BY month ASC', year=int(year))
    invoices = query.fetch(1000)

    fname = year + '_invoice.csv'
    response = HttpResponse(mimetype='text/csv')
    response['Content-Disposition'] = 'attachment; filename=' + fname

    writer = csv.writer(response)

    for invoice in invoices:
        if invoice.status == INVOICE_STATUS[0]:
            if invoice.due_date < date.today():
                invoice.status = INVOICE_STATUS[2]
                invoice.put()

        writer.writerow([
                         invoice.no,
                         _kr(invoice.school.name),
                         invoice.year,
                         invoice.month,
                         invoice.invoiced_date,
                         invoice.due_date,
                         invoice.start_date,
                         invoice.end_date,
                         invoice.uint_price,
                         invoice.count_classes,
                         invoice.total_price,
                         invoice.pay_date,
                         invoice.status,
                         _kr(invoice.note),
                        ])
    return response

@admin_required
@render_to('temp_invoice/month_list.html')
def month_list(request, year, month):
    query = TempInvoice.gql('WHERE year=:year AND month=:month ORDER BY month ASC', year=int(year), month=int(month))
    invoices = query.fetch(1000)

    all_schools = School.gql('Where year=:year', year=int(year)).fetch(1000)
    unregistered_schools_ids = set([s.id for s in all_schools]) - \
                        set([invoice.school.id for invoice in invoices])
    unregistered_schools = []
    for school_id in unregistered_schools_ids:
        s = School.gql('Where id=:school_id', school_id=school_id).fetch(1)[0]
        unregistered_schools.append(s)

    for invoice in invoices:
        if invoice.status == INVOICE_STATUS[0]:
            if invoice.due_date < date.today():
                invoice.status = INVOICE_STATUS[2]
                invoice.put()

    paid = sum([invoice.total_price for invoice in invoices if invoice.status == INVOICE_STATUS[1]])
    unpaid = sum([invoice.total_price for invoice  in invoices if invoice.status != INVOICE_STATUS[1]])
    total_paid = sum([invoice.total_price for invoice  in invoices])
    unpaid_school = sum([1 for invoice  in invoices if invoice.status != INVOICE_STATUS[1]])
    paid_school = sum([1 for invoice  in invoices if invoice.status == INVOICE_STATUS[1]])
    total_class_count = sum([invoice.count_classes for invoice  in invoices])

    eteacher_pay = ETEACHER_PAY * DALLA * total_class_count
    return {
            'invoices': invoices,
            'paid': paid,
            'unpaid': unpaid,
            'total_paid': total_paid,
            'unpaid_school': unpaid_school,
            'paid_school': paid_school,
            'year': year,
            'month': month,
            'total_class_count': total_class_count,
            'eteacher_pay': eteacher_pay,
            'unregistered_schools': unregistered_schools,
            }

@admin_required
@render_to('temp_invoice/school_list.html')
def school_list(request, school_id, year):
    school = School.get_using_id(int(school_id))
    query = TempInvoice.gql('WHERE school=:school AND year=:year ORDER BY month ASC', school=school.key(), year=int(year))
    invoices = query.fetch(1000)

    for invoice in invoices:
        if invoice.status == INVOICE_STATUS[0]:
            if invoice.due_date < date.today():
                invoice.status = INVOICE_STATUS[2]
                invoice.put()


    unpaid_dic = {}
    paid_dic = {}
    total_paid_dic = {}
    total_class_count_dic = {}
    for m in xrange(1, 13):
        query = TempInvoice.gql('WHERE school=:school AND year=:year AND month=:month ORDER BY month ASC', school=school.key(), year=int(year), month=int(m))
        month_invoices = query.fetch(1000)
        paid_dic[m] = sum([month.total_price for month in month_invoices if month .status == INVOICE_STATUS[1]])
        unpaid_dic[m] = sum([month.total_price for month  in month_invoices if month .status != INVOICE_STATUS[1]])
        total_paid_dic[m] = sum([month.total_price for month  in month_invoices])
        total_class_count_dic[m] = sum([month.count_classes for month  in month_invoices])

    paid_dic[13] = sum(paid_dic.values())
    unpaid_dic[13] = sum(unpaid_dic.values())
    total_paid_dic[13] = sum(total_paid_dic.values())
    total_class_count_dic[13] = sum(total_class_count_dic.values())

    return {
            'invoices': invoices,
            'school': school,
            'paid_dic': paid_dic,
            'unpaid_dic': unpaid_dic,
            'total_paid_dic': total_paid_dic,
            'total_class_count_dic': total_class_count_dic,
            }